#include "timer.h"
#include "uart.h"
#include "interrupt.h"

// 系统启动时间 (ms)
static volatile uint64_t system_ticks = 0;

// 读取mtime寄存器 (当前时钟计数)
static inline uint64_t read_mtime(void) {
    volatile uint64_t* mtime_ptr = (volatile uint64_t*)CLINT_MTIME;
    return *mtime_ptr;
}

// 写入mtimecmp寄存器 (下一次触发中断的时间点)
static inline void write_mtimecmp(uint64_t val) {
    // 使用hartid 0 (单核)
    volatile uint64_t* mtimecmp_ptr = (volatile uint64_t*)CLINT_MTIMECMP(0);
    *mtimecmp_ptr = val;
}

// 启用时钟中断
void timer_init(void) {
    // 启用M模式的时钟中断
    uint64_t mie;
    asm volatile("csrr %0, mie" : "=r"(mie));
    mie |= (1UL << IRQ_M_TIMER);
    asm volatile("csrw mie, %0" : : "r"(mie));
    
    // 设置首次中断
    timer_set(TIMER_INTERVAL_DEFAULT);
    
    uart_puts("Timer initialized, interrupt every 1 second\n");
}

// 设置下一次中断的时间
void timer_set(uint64_t interval) {
    uint64_t current_time = read_mtime();
    write_mtimecmp(current_time + interval);
}

// 获取当前时钟计数
uint64_t timer_read(void) {
    return read_mtime();
}

// 时钟中断处理函数
void timer_handler(void) {
    system_ticks++;
    
    // 每触发一次中断打印一条消息
    uart_puts("Tick: ");
    
    // 简单转换ticks为字符串
    char tick_str[20];
    uint64_t ticks = system_ticks;
    int i = 0;
    
    // 转换数字为字符串
    do {
        tick_str[i++] = (ticks % 10) + '0';
        ticks /= 10;
    } while (ticks > 0);
    
    // 反转字符串
    for (int j = 0; j < i/2; j++) {
        char temp = tick_str[j];
        tick_str[j] = tick_str[i-j-1];
        tick_str[i-j-1] = temp;
    }
    tick_str[i] = '\0';
    
    uart_puts(tick_str);
    uart_puts(" s\n");
    
    // 设置下一次中断
    timer_set(TIMER_INTERVAL_DEFAULT);
}

// 计算系统运行时间 (毫秒)
unsigned long timer_uptime_ms(void) {
    // 将系统ticks转换为ms (假设1个tick是1秒)
    return system_ticks * 1000;
}
